using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using DirkRettschlag.Utils;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace Departure
{
    public partial class ctrlStationList : UserControl
    {
        #region Delegates

        delegate void OnUpdateStatusCallback(string status);
        public delegate void StationDblClickedCallback(string key);
        public delegate void StationSelectedCallback(string key);

        #endregion Delegates

        #region Events

        public event StationDblClickedCallback OnStationDblClicked;
        public event StationSelectedCallback OnStationSelected;

        #endregion Events

        #region Variables

        SkinSettings skinSettings;
        bool vga;
        Rectangle rectangleImageBG;
        string status = string.Empty;

        // Background drawing
        Bitmap backBufferBitmap;
        Graphics backBuffer;

        #endregion Variables

        #region Properties

        public SkinSettings SkinSettings
        {
            set 
            {
                this.skinSettings = value;
                this.ForeColor = skinSettings.FontColor;
                this.kListControlStation.SkinSettings = skinSettings;

                this.ctrlLabelHeader.SkinSettings = skinSettings;
                this.ctrlLabelHeader.ImageBG = skinSettings.BackGroundHeader;
                
                this.ctrlLabelStatus.SkinSettings = skinSettings;
                this.ctrlLabelStatus.ImageBG = skinSettings.BackGroundStatus;

                rectangleImageBG = new Rectangle(0, 0, skinSettings.BackGround.Width, skinSettings.BackGround.Height);
                
                Invalidate();
            }
        }

        public bool VGA
        {
            get { return this.vga; }
            set 
            {
                this.vga = value;
                this.kListControlStation.VGA = vga;
                this.ctrlLabelHeader.VGA = vga;
                this.ctrlLabelStatus.VGA = vga;

                if (vga)
                    this.kListControlStation.MaxVelocity = 30;
                else
                    this.kListControlStation.MaxVelocity = 15;

                SetScaleDimensions();

            }
        }

        public string Status
        {
            get
            {
                return ctrlLabelStatus.Text;
            }
            set
            {
                ctrlLabelStatus.Text = value;
            }
        }

        public bool IsFocused
        {
            get { return kListControlStation.IsFocused; }
            set { kListControlStation.IsFocused = value; }
        }

        public KListControl KListControlStation
        {
            get { return this.kListControlStation; }
        }

        #endregion Properties
                
        #region Constructor

        public ctrlStationList()
        {
            InitializeComponent();

            this.kListControlStation.HookKeyDown(this);
            this.kListControlStation.WideFastAccess = true;

            this.ctrlLabelHeader.Text = "Stations";
            this.ctrlLabelHeader.TextHorizontalAlignment = ctrlLabel.TextHAlignment.Center;
            this.ctrlLabelStatus.TextHorizontalAlignment = ctrlLabel.TextHAlignment.Left;

            SetScaleDimensions();

            CreateBackBuffer();

        }

        public ctrlStationList(SkinSettings skinSettings, bool vga)
        {
            InitializeComponent();

            this.skinSettings = skinSettings;

            this.vga = vga;
            this.kListControlStation.VGA = vga;

            this.kListControlStation.HookKeyDown(this);
            this.kListControlStation.WideFastAccess = true;
            if (vga)
                this.kListControlStation.MaxVelocity = 30;
            else
                this.kListControlStation.MaxVelocity = 15;

            this.ctrlLabelHeader.SkinSettings = skinSettings;
            this.ctrlLabelHeader.VGA = vga;
            this.ctrlLabelHeader.ImageBG = skinSettings.BackGroundHeader;
            this.ctrlLabelHeader.TextHorizontalAlignment = ctrlLabel.TextHAlignment.Center;

            this.ctrlLabelStatus.SkinSettings = skinSettings;
            this.ctrlLabelStatus.VGA = vga;
            this.ctrlLabelStatus.ImageBG = skinSettings.BackGroundStatus;
            this.ctrlLabelStatus.TextHorizontalAlignment = ctrlLabel.TextHAlignment.Left;

            this.ctrlLabelHeader.Text = "Stations";

            SetScaleDimensions();

            CreateBackBuffer();

        }
        #endregion Constructor

        #region Public Methods

        public void HookKeyDown(Control control)
        {
            control.KeyDown += new KeyEventHandler(OnKeyDown);
        }

        public void AddStationItem(string StationName, string Key)
        {
            AddStationItem(this.kListControlStation, StationName, Key);
        }

        delegate void AddStationItemCallback(Control co, string StationName, string Key);
        public void AddStationItem(Control co, string StationName, string Key)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (co.InvokeRequired)
            {
                AddStationItemCallback d = new AddStationItemCallback(AddStationItem);
                co.Invoke(d, new object[] { co, StationName, Key });
            }
            else
            {
                ctrlStationListItem stationItem = new ctrlStationListItem(this.kListControlStation, StationName, Key, vga);

                stationItem.XIndex = 0;
                stationItem.YIndex = kListControlStation.Count(0);
                stationItem.FastAccessValue = stationItem.StationName;

                kListControlStation.AddItem(stationItem);

            }
        }

        public void RemoveStationItem(string Key)
        {

            kListControlStation.RemoveItem(kListControlStation.GetItemByKey(Key));

        }

        public void SelectStationItem(string Key)
        {

            kListControlStation.SelectedItem = kListControlStation.GetItemByKey(Key);

        }

        public void SetScaleDimensions()
        {
            if (vga)
            {
                this.kListControlStation.ItemHeight = 64;

                this.kListControlStation.FastAccessWidth = 40;
            }
            else
            {
                this.kListControlStation.ItemHeight = 32;

                this.kListControlStation.FastAccessWidth = 20;
            }

        }
        
        public void SortStations()
        {
            this.kListControlStation.SortItems();
        }
        public void OrderStations(List<string> order)
        {
            this.kListControlStation.OrderItems(order);
        } 
        #endregion Public Methods

        #region Private Methods

        private void kListControlStation_OnItemDoubleClicked(object sender, EventArgs e)
        {
            if (sender.GetType() == this.GetType())
            {
                ctrlStationListItem item = (ctrlStationListItem)kListControlStation.SelectedItem;

                if (item != null)
                {
                    if (OnStationDblClicked != null)
                        OnStationDblClicked(item.Key);
                }
            }
        }

        private void kListControlStation_SelectedItemChanged(object sender, EventArgs e)
        {
            ctrlStationListItem item = (ctrlStationListItem)kListControlStation.SelectedItem;

            if (item != null)
            {
                if (OnStationSelected != null)
                    OnStationSelected(item.Key);
            }
        }

        private void kListControlStation_SelectedItemClicked(object sender, EventArgs e)
        {
            ctrlStationListItem item = (ctrlStationListItem)kListControlStation.SelectedItem;

            if (item != null)
            {
                if (OnStationSelected != null)
                    OnStationSelected(item.Key);
            }
        }
                
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.kListControlStation.ItemWidth = this.ClientSize.Width;
            if (skinSettings != null) 
                rectangleImageBG = new Rectangle(0, 0, skinSettings.BackGround.Width, skinSettings.BackGround.Height);
            CreateBackBuffer();
            Invalidate();
        }



        /// <summary>
        /// Paints the background of the control.
        /// </summary>
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // Do nothing
        }

        /// <summary>
        /// Paints the control.
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (backBuffer != null)
            {
                backBuffer.DrawImage(skinSettings.BackGround, this.ClientRectangle, rectangleImageBG, GraphicsUnit.Pixel);

                if (vga)
                    backBuffer.DrawString(status, this.Font, new SolidBrush(skinSettings.FontColor), 1, this.Bounds.Height - 32);
                else
                    backBuffer.DrawString(status, this.Font, new SolidBrush(skinSettings.FontColor), 1, this.Bounds.Height - 16);

                e.Graphics.DrawImage(backBufferBitmap, 0, 0);
            }
            else
            {
                base.OnPaint(e);
            }
        }

        /// <summary>
        /// Cleans up the background paint buffer.
        /// </summary>
        private void CleanupBackBuffer()
        {
            if (backBufferBitmap != null)
            {
                backBufferBitmap.Dispose();
                backBufferBitmap = null;
                backBuffer.Dispose();
                backBuffer = null;
            }
        }

        /// <summary>
        /// Creates the background paint buffer.
        /// </summary>
        private void CreateBackBuffer()
        {
            CleanupBackBuffer();

            backBufferBitmap = new Bitmap(Bounds.Width, Bounds.Height);
            backBuffer = Graphics.FromImage(backBufferBitmap);
        }

        public void OnUpdateStatus(string status)
        {
            if (this.InvokeRequired)
            {
                OnUpdateStatusCallback d = new OnUpdateStatusCallback(OnUpdateStatus);
                this.Invoke(d, new object[] { status });
            }
            else
            {
                this.status = status;
                Invalidate();
            }
        }

        protected void OnKeyDown(object sender, KeyEventArgs e)
        {
            base.OnKeyDown(e);
        }

        #endregion Private Methods

 

    }
}
